import { CloseOutlined, LoadingOutlined, RightOutlined, SearchOutlined } from '@ant-design/icons';
import { useScroll } from 'ahooks';
import { Breadcrumb, Button, Checkbox, Input, message, ModalProps, Popover } from 'antd';
import { debounce } from 'lodash';
import { ChangeEvent, useCallback, useEffect, useRef, useState } from 'react';

import orgService from '@/api/services/orgService';
import {
  GetGroupTreeList,
  GetOrgGroupUserInfoReq,
  GetOrgGroupUserInfoRes,
  GroupUserInfoList,
} from '@/common/types';
import { useDatasetStore } from '@/store/datasetStore';
import { treeToPlainList } from '@/utils/tree';

import SvgIcon from '../icon/svg-icon';
import { CircleLoading } from '../loading';
import Modals from '../modals/Modals';
import NotData from '../NotData';

interface Props extends ModalProps {
  appId: string;
  onSubmit: (value: SubmitType[]) => void;
  isCheckBox?: boolean;
  onCancel: () => void;
  defaultValue?: any[];
  disabled?: any[];
  submitStatus?: boolean;
}

export type SubmitType = (SelectedValues & { type: 'group' }) | (SelectedValues & { type: 'user' });

type SharedFields = keyof GetGroupTreeList & keyof GroupUserInfoList;
type ExclusiveFields = Partial<
  Omit<GetGroupTreeList, SharedFields> & Omit<GroupUserInfoList, SharedFields>
>;

type SelectedValues = Pick<GetGroupTreeList, SharedFields> & ExclusiveFields;

const PersonnelModal = ({
  appId,
  onSubmit,
  isCheckBox = false,
  defaultValue,
  disabled,
  submitStatus = false,
  ...props
}: Props) => {
  const containerRef = useRef(null);
  const scroll = useScroll(containerRef);
  const [messageApi, contextHolder] = message.useMessage();
  const { getUngroupedId } = useDatasetStore();
  const [groupValue, setGroupValue] = useState<GetGroupTreeList[]>([]);
  const [userValue, setUserValue] = useState<GetOrgGroupUserInfoRes['list']>([]);
  const [selectedValue, setSelectValue] = useState<SelectedValues[]>([]);
  const [pagination, setPagination] = useState<GetOrgGroupUserInfoReq>({
    page: 1,
    page_size: 10,
    group_id: '',
    searchText: '',
  });
  const [paginationStatus, setPaginationStatus] = useState(false);
  const [paginationTotal, setPaginationTotal] = useState(0);
  const [breadcrumnValue, setBreadCrumnValue] = useState<GetGroupTreeList[]>([]);
  const [groupLoading, setGroupLoading] = useState<boolean>(false);
  const [searchText, setSearchText] = useState('');
  const [tree, setTree] = useState<GetGroupTreeList[]>([]);

  useEffect(() => {
    if (appId) {
      getGroup();
    }
  }, [appId, isCheckBox]);

  useEffect(() => {
    setSelectValue(defaultValue ?? []);
  }, [defaultValue]);

  const getGroup = (searchText?: string, paginationValue?: any) => {
    setGroupLoading(true);
    orgService
      .getOrgGroupTreeList(searchText)
      .then((res) => {
        if (res.length === 0) {
          setGroupValue([]);
        }
        const plainList = treeToPlainList(res);
        const { id } = plainList.filter((item) => item.name === '未分组')[0]; // 获取到未分组的id
        getUngroupedId(id);

        if (!searchText) {
          setTree(res);
        }

        if (searchText) {
          setGroupValue(res);
          return;
        }

        if (isCheckBox) {
          setGroupValue(res);
          setUserValue([]);
          const temp = {
            id: 'root',
            name: '组织管理',
            parent_id: 'root',
            description: '',
            user_count: 0,
            children: res,
            create_time: '',
            system_code: '',
          };
          setBreadCrumnValue([temp]);
        } else {
          handleNext(res[0], false, paginationValue);
          setGroupValue(res[0].children);
          setBreadCrumnValue(res);
        }
      })
      .catch(() => {
        setGroupValue([]);
      })
      .finally(() => {
        setGroupLoading(false);
      });
  };

  const findPath = (data: string) => {
    if (!tree) return null;

    const treeData = tree[0].children;
    const result = treeData.find((item: any) => item.id === data);

    return result;
  };

  const handleNext = (item: GetGroupTreeList, type = true, paginationValue?: any) => {
    setSearchText('');

    if (item.parent_id && item.parent_id.includes('root')) {
      setGroupValue(item.children);
      setUserValue([]);
      return;
    }

    const paginationData = paginationValue || pagination;

    orgService
      .getUser({ ...paginationData, group_id: item.id, page: 1, searchText: '' })
      .then((res) => {
        if (item.level > 1) {
          const result = findPath(item.parent_id);
          const breadValue = [tree[0], result, item];

          if (isCheckBox) {
            breadValue.unshift({
              id: 'root',
              name: '组织管理',
              parent_id: 'root',
              description: '',
              user_count: 0,
              children: tree,
              create_time: '',
              system_code: '',
              level: -1,
            });
          }
          setBreadCrumnValue(breadValue);
        } else if (type) {
          setBreadCrumnValue([...breadcrumnValue, item]);
        }

        setPagination({ ...paginationData, group_id: item.id, page: 1, searchText: '' });
        setUserValue(res.list);
        setGroupValue(item.children);
        setPaginationTotal(res.total);
      });
  };

  const handleUser = (e: any) => {
    const { value } = e.target;
    const index = selectedValue.findIndex((item) => item.id === value.id);
    if (index === -1) {
      setSelectValue([value, ...selectedValue]);
    } else {
      setSelectValue(selectedValue.filter((item) => item.id !== value.id));
    }
  };

  const handleSelectCancel = (value: SelectedValues) => {
    if (disabled?.some((item) => item === value.id)) {
      message.error('');
    }
    setSelectValue(selectedValue.filter((item) => item.id !== value.id));
  };

  useEffect(() => {
    if (containerRef.current) {
      const { scrollHeight, clientHeight } = containerRef.current;
      const scrollTop = scroll?.top || 0;
      const distanceFromBottom = scrollHeight - scrollTop - clientHeight;

      // 判断是否距离底部100px以内
      if (distanceFromBottom <= 100 && scrollTop > 100) {
        handleGetUser();
      }
    }
  }, [scroll]);

  const handleGetUser = () => {
    if (userValue.length === paginationTotal) {
      return;
    }

    if (!paginationStatus) {
      setPaginationStatus(true);
      orgService
        .getUser({ ...pagination, page: pagination.page + 1 })
        .then((res) => {
          setPagination({ ...pagination, page: pagination.page + 1 });
          setUserValue([...userValue, ...res.list]);
        })
        .finally(() => {
          setPaginationStatus(false);
        });
    }
  };

  const handleBreadcrumb = (value: GetGroupTreeList) => {
    handleNext(value, false);
    if (value.system_code === 'root') {
      setGroupValue(value.children);
    } else {
      setGroupValue(value.children);
    }
    const findValue = breadcrumnValue.findIndex((item) => item.id === value.id);

    const temp = [...breadcrumnValue];
    const result = temp.slice(0, findValue + 1);
    setBreadCrumnValue(result);
  };

  // 判断是否为部门
  const isGroup = (item: SelectedValues): item is GetGroupTreeList => {
    return 'children' in item && Array.isArray(item.children);
  };

  // 确定提交
  const handleOk = (): void => {
    if (submitStatus && selectedValue.length === 0) {
      messageApi.open({
        type: 'warning',
        content: '至少选择一个人员/组织',
      });
      return;
    }

    const result: SubmitType[] = selectedValue.map((item) => {
      if (item.type) {
        return { ...item };
      }

      if (isGroup(item)) {
        return { ...item, type: 'group' };
      }
      return { ...item, type: 'user' };
    });
    onSubmit(result);
  };

  const searchPersonnel = (e: ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    const paginationValue = {
      page: 1,
      page_size: 10,
      searchText: value,
    };
    setPagination({ ...paginationValue, page: 1 });
    getGroup(value, paginationValue);

    orgService
      .getUser({ ...paginationValue, page: 1 })
      .then((res) => {
        setUserValue([...res.list]);
        setPaginationTotal(res.total);
      })
      .finally(() => {
        setPaginationStatus(false);
      });
  };

  const searchPersonnelFn = useCallback(
    debounce((e: ChangeEvent<HTMLInputElement>) => {
      searchPersonnel(e);
    }, 800),
    [],
  );

  const initializeState = () => {
    const paginationData = {
      page: 1,
      page_size: 10,
      group_id: appId,
      searchText: '',
    };
    setSearchText('');
    setPagination(paginationData);
    getGroup('', paginationData);
    setSelectValue(defaultValue ?? []);
  };

  const afterClose = () => {
    initializeState();
  };

  const iconName = (level?: number) => {
    if (level === 0) {
      return 'ai-classa';
    }
    if (level === 1) {
      return 'ai-classb';
    }

    if (level === 2) {
      return 'ai-calssc';
    }

    return 'ai-classd';
  };

  return (
    <>
      {contextHolder}
      <Modals
        {...props}
        onOk={handleOk}
        width={720}
        afterClose={afterClose}
        // footerOkDisabled={selectedValue.length === 0}
      >
        <div
          className="flex h-[310px]  rounded-xl"
          style={{
            border: '1px solid #ECEEFA',
          }}
        >
          <div className="flex w-1/2  flex-col pl-[15px] pt-[15px]">
            <div className="pr-[22px]">
              <Input
                placeholder="搜索用户组、部门、或用户"
                prefix={<SearchOutlined />}
                onChange={(e) => {
                  searchPersonnelFn(e);
                  setSearchText(e.target.value);
                }}
                value={searchText}
              />
            </div>

            {groupLoading ? (
              <div className="flex-1">
                <CircleLoading />
              </div>
            ) : (
              <>
                <div className="pr-[22px]">
                  <div className="mt-[15px]">
                    {pagination.searchText.trim().length === 0 && (
                      <Breadcrumb
                        separator=">"
                        items={breadcrumnValue.map((item, index) => ({
                          key: item.id,
                          title: (
                            <a
                              onClick={() =>
                                index === breadcrumnValue.length - 1
                                  ? undefined
                                  : handleBreadcrumb(item)
                              }
                              className={`${
                                index === breadcrumnValue.length - 1
                                  ? '!text-black'
                                  : '!text-@brand-color'
                              }`}
                            >
                              {item.name}
                            </a>
                          ),
                        }))}
                      />
                    )}
                  </div>
                </div>

                <div
                  className={`overflow-y-auto pr-[22px] ${
                    breadcrumnValue.length > 0 ? 'h-[224px]' : 'h-[220px]'
                  }`}
                  ref={containerRef}
                >
                  {groupValue.length === 0 && userValue.length === 0 ? (
                    <NotData />
                  ) : (
                    <>
                      <div className="mt-[15px] flex flex-col gap-[15px]">
                        {groupValue.map((item) => {
                          if (isCheckBox) {
                            return (
                              <div key={item.id} className="flex items-center justify-between">
                                {item.user_count > 0 || item.children.length > 0 ? (
                                  <Popover content="下级部门将被同时授权" color="gold-inverse">
                                    <Checkbox
                                      value={item}
                                      onChange={handleUser}
                                      checked={
                                        selectedValue.some((v) => v.id === item.id) ||
                                        disabled?.some((v) => v.id === item.id)
                                      }
                                      disabled={
                                        !(item.user_count > 0 || item.children.length > 0) ||
                                        disabled?.some((v) => v.id === item.id)
                                      }
                                    >
                                      {/* <div className="flex items-center gap-2">
                                      <SvgIcon icon={iconName(item.level)} />
                                      <div>{item.name}</div>
                                    </div> */}
                                    </Checkbox>
                                  </Popover>
                                ) : (
                                  <Checkbox
                                    value={item}
                                    onChange={handleUser}
                                    checked={
                                      selectedValue.some((v) => v.id === item.id) ||
                                      disabled?.some((v) => v.id === item.id)
                                    }
                                    disabled={
                                      !(item.user_count > 0 || item.children.length > 0) ||
                                      disabled?.some((v) => v.id === item.id)
                                    }
                                  >
                                    {/* <div className="flex items-center gap-2">
                                    <SvgIcon icon={iconName(item.level)} />
                                    <div>{item.name}</div>
                                  </div> */}
                                  </Checkbox>
                                )}

                                <div
                                  className="ml-2 flex flex-1 cursor-pointer items-center justify-between"
                                  onClick={
                                    !(item.user_count > 0 || item.children.length > 0)
                                      ? undefined
                                      : () => handleNext(item)
                                  }
                                >
                                  <div className="flex items-center gap-2">
                                    <SvgIcon icon={iconName(item.level)} />
                                    <div>{item.name}</div>
                                  </div>

                                  <Button
                                    type="text"
                                    // color="primary"
                                    // variant="text"
                                    disabled={!(item.user_count > 0 || item.children.length > 0)}
                                    // onClick={() => handleNext(item)}
                                  >
                                    <RightOutlined />
                                  </Button>
                                </div>
                              </div>
                            );
                          }

                          return (
                            <div
                              key={item.id}
                              className="flex cursor-pointer items-center justify-between"
                              onClick={() =>
                                !(item.user_count > 0 || item.children.length > 0)
                                  ? undefined
                                  : handleNext(item)
                              }
                            >
                              <div className="flex items-center gap-2  text-[14px] text-[#474C5F]">
                                <SvgIcon icon={iconName(item.level)} />

                                <div>{item.name}</div>
                              </div>
                              <Button
                                type="text"
                                // color="primary"
                                // variant="text"
                                disabled={!(item.user_count > 0 || item.children.length > 0)}
                                // onClick={() => handleNext(item)}
                              >
                                <RightOutlined />
                              </Button>
                            </div>
                          );
                        })}
                      </div>

                      <div className="mt-[15px] flex flex-col gap-[15px]">
                        {userValue.map((item) => (
                          <div key={item.id}>
                            <Checkbox
                              value={item}
                              onChange={handleUser}
                              checked={
                                selectedValue.some((v) => v.id === item.id) ||
                                disabled?.some((v) => v.id === item.id)
                              }
                              disabled={
                                disabled?.some((v) => v.id === item.id) ||
                                item.role.code === 'super_admin'
                              }
                            >
                              <div className="flex items-center gap-2">
                                <SvgIcon icon="ai-classd" />
                                <div>{item.name}</div>
                              </div>
                            </Checkbox>
                          </div>
                        ))}
                      </div>

                      {paginationStatus && (
                        <div className="flex items-center justify-center text-[#6640FF]">
                          <LoadingOutlined />
                          <div className="ml-2">加载中.....</div>
                        </div>
                      )}
                    </>
                  )}
                </div>
              </>
            )}
          </div>

          <div
            className="w-1/2 pl-[11px] pr-[7px] pt-[23px] text-sm text-[#474C5F]"
            style={{ borderLeft: '1px solid #ECEEFA' }}
          >
            <div className="mb-[22px]">已选:{selectedValue.length}个</div>
            <div className="h-[240px] overflow-y-auto">
              {selectedValue.map((item) => {
                if (disabled?.some((v) => v.id === item.id)) {
                  return (
                    <Popover content="无法操作" key={item.id}>
                      <div className="flex cursor-not-allowed items-center py-[6px] pl-[5px] pr-[11px] text-[#989A9E]">
                        {/* <SvgIcon icon={iconName(item.level)} /> */}
                        <span>{item.name}</span>
                      </div>
                    </Popover>
                  );
                }

                return (
                  <div
                    key={item.id}
                    className="flex items-center justify-between py-[6px] pl-[5px] pr-[11px] hover:bg-[#D9D9D980]"
                  >
                    <div>
                      {/* <SvgIcon icon={iconName(item.level)} /> */}
                      <span>{item.name}</span>
                    </div>
                    <div className="cursor-pointer" onClick={() => handleSelectCancel(item)}>
                      <CloseOutlined />
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </Modals>
    </>
  );
};

export default PersonnelModal;
